package client.messages.commands;

import client.MapleCharacter;
import client.MapleClient;
import client.inventory.IItem;
import client.inventory.MapleInventoryType;
import constants.ServerConstants;
import handling.channel.ChannelServer;
import handling.world.World;
import java.util.Map;
import java.util.Map.Entry;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.maps.MapleMap;
import tools.ArrayMap;
import tools.Pair;
import tools.StringUtil;

public class GMCommand {
	public static ServerConstants.PlayerGMRank getPlayerLevelRequired() {
		return ServerConstants.PlayerGMRank.GM;
	}
	
	public static class WarpHere extends CommandExecute {
		
		@Override
		public int execute(MapleClient c, String[] splitted) {
			MapleCharacter victim = c.getChannelServer().getPlayerStorage().getCharacterByName(splitted[1]);
			if (victim != null) {
				victim.changeMap(c.getPlayer().getMap(),
						c.getPlayer().getMap().findClosestSpawnpoint(c.getPlayer().getPosition()));
			} else {
				int ch = World.Find.findChannel(splitted[1]);
				if (ch < 0) {
					c.getPlayer().dropMessage(5, "角色不在线");
					return 1;
				}
				victim = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(splitted[1]);
				c.getPlayer().dropMessage(5, "正在传送玩家到身边");
				victim.dropMessage(5, "GM正在传送你");
				if (victim.getMapId() != c.getPlayer().getMapId()) {
					MapleMap mapp = victim.getClient().getChannelServer().getMapFactory()
							.getMap(c.getPlayer().getMapId());
					victim.changeMap(mapp, mapp.getPortal(0));
				}
				victim.changeChannel(c.getChannel());
			}
			return 1;
		}
	}

	public static class UnBan extends CommandExecute {
		protected boolean hellban = false;

		private String getCommand() {
			return "UnBan";
		}

		@Override
		public int execute(MapleClient c, String[] splitted) {
			if (splitted.length < 2) {
				c.getPlayer().dropMessage(6, "[Syntax] !" + getCommand() + " <原因>");
				return 0;
			}
			byte ret;
			if (this.hellban) {
				ret = MapleClient.unHellban(splitted[1]);
			} else {
				ret = MapleClient.unban(splitted[1]);
			}
			if (ret == -2) {
				c.getPlayer().dropMessage(6, "[" + getCommand() + "] SQL error.");
				return 0;
			}
			if (ret == -1) {
				c.getPlayer().dropMessage(6, "[" + getCommand() + "] The character does not exist.");
				return 0;
			}
			c.getPlayer().dropMessage(6, "[" + getCommand() + "] Successfully unbanned!");

			byte ret_ = MapleClient.unbanIPMacs(splitted[1]);
			if (ret_ == -2) {
				c.getPlayer().dropMessage(6, "[UnbanIP] SQL error.");
			} else if (ret_ == -1) {
				c.getPlayer().dropMessage(6, "[UnbanIP] The character does not exist.");
			} else if (ret_ == 0) {
				c.getPlayer().dropMessage(6, "[UnbanIP] No IP or Mac with that character exists!");
			} else if (ret_ == 1) {
				c.getPlayer().dropMessage(6, "[UnbanIP] IP/Mac -- one of them was found and unbanned.");
			} else if (ret_ == 2) {
				c.getPlayer().dropMessage(6, "[UnbanIP] Both IP and Macs were unbanned.");
			}
			return ret_ > 0 ? 1 : 0;
		}
	}

	public static class DC extends CommandExecute {
		
		@Override
		public int execute(MapleClient c, String[] splitted) {
        	if (splitted.length < 2) {
        		c.getPlayer().dropMessage(6, "踢人用法: !dc [玩家名称]");
        		return 0;
        	}
			ChannelServer.forceRemovePlayerByCharName(splitted[1]);
			c.getPlayer().dropMessage("解除卡号卡角成功");
			return 1;
		}
	}

	public static class Job extends CommandExecute {
		
		@Override
		public int execute(MapleClient c, String[] splitted) {
        	if (splitted.length < 2) {
        		c.getPlayer().dropMessage(6, "修改职业用法: !job [职业ID]");
        		return 0;
        	}
			c.getPlayer().changeJob(Integer.parseInt(splitted[1]));
			return 1;
		}
	}

	public static class GainMeso extends CommandExecute {
		
		@Override
		public int execute(MapleClient c, String[] splitted) {
			c.getPlayer().gainMeso(Integer.MAX_VALUE - c.getPlayer().getMeso(), true);
			return 1;
		}
	}

	public static class Level extends CommandExecute {
		
		@Override
		public int execute(MapleClient c, String[] splitted) {
			c.getPlayer().setLevel(Short.parseShort(splitted[1]));
			c.getPlayer().levelUp();
			if (c.getPlayer().getExp() < 0) {
				c.getPlayer().gainExp(-c.getPlayer().getExp(), false, false, true);
			}
			return 1;
		}
	}

	public static class spy extends CommandExecute {
		
		@SuppressWarnings("unused")
		@Override
		public int execute(MapleClient c, String[] splitted) {
			if (splitted.length < 2) {
				c.getPlayer().dropMessage(6, "读取玩家信息使用规则: !spy <玩家名字>");
			} else {
				MapleCharacter victim = c.getChannelServer().getPlayerStorage().getCharacterByName(splitted[1]);
				if ((victim.getGMLevel() > c.getPlayer().getGMLevel()) && (c.getPlayer().getId() != victim.getId())) {
					c.getPlayer().dropMessage(5, "你不能查看比你高权限的人!");
					return 0;
				}
				if (victim != null) {
					c.getPlayer().dropMessage(5, "此玩家(" + victim.getId() + ")状态:");
					c.getPlayer().dropMessage(5,
							"等級: " + victim.getLevel() + "职业: " + victim.getJob() + "名声: " + victim.getFame());
					c.getPlayer().dropMessage(5,
							"地图: " + victim.getMapId() + " - " + victim.getMap().getMapName().toString());
					c.getPlayer().dropMessage(5,
							"力量: " + victim.getStat().getStr() + "  ||  敏捷: " + victim.getStat().getDex() + "  ||  智力: "
									+ victim.getStat().getInt() + "  ||  运气: " + victim.getStat().getLuk());
					c.getPlayer().dropMessage(5, "拥有 " + victim.getMeso() + " 金币.");
				} else {
					c.getPlayer().dropMessage(5, "找不到此玩家.");
				}
			}
			return 1;
		}
	}

	public static class online extends CommandExecute {
		
		@Override
		public int execute(MapleClient c, String[] splitted) {
			int total = 0;
			int curConnected = c.getChannelServer().getConnectedClients();
			c.getPlayer().dropMessage(6,
					"-------------------------------------------------------------------------------------");
			c.getPlayer().dropMessage(6, "頻道: " + c.getChannelServer().getChannel() + " 线上人数: " + curConnected);
			total += curConnected;
			for (MapleCharacter chr : c.getChannelServer().getPlayerStorage().getAllCharacters()) {
				if ((chr != null) && (c.getPlayer().getGMLevel() >= chr.getGMLevel())) {
					StringBuilder ret = new StringBuilder();
					ret.append(" 角色名称 ");
					ret.append(StringUtil.getRightPaddedStr(chr.getName(), ' ', 15));
					ret.append(" ID: ");
					ret.append(StringUtil.getRightPaddedStr(chr.getId() + "", ' ', 4));
					ret.append(" 等级: ");
					ret.append(StringUtil.getRightPaddedStr(String.valueOf(chr.getLevel()), ' ', 4));
					ret.append(" 职业: ");
					ret.append(chr.getJob());
					if (chr.getMap() != null) {
						ret.append(" 地图: ");
						ret.append(chr.getMapId());
						ret.append("(").append(chr.getMap().getMapName()).append(")");
						c.getPlayer().dropMessage(6, ret.toString());
					}
				}
			}
			c.getPlayer().dropMessage(6, "当前频道总计在线人数: " + total);
			c.getPlayer().dropMessage(6,
					"-------------------------------------------------------------------------------------");
//			int channelOnline = c.getChannelServer().getConnectedClients();
			int totalOnline = 0;
			for (ChannelServer cserv : ChannelServer.getAllInstances()) {
				totalOnline += cserv.getConnectedClients();
			}
			c.getPlayer().dropMessage(6, "当前服务器总计在线人数: " + totalOnline + "个");
			c.getPlayer().dropMessage(6,
					"-------------------------------------------------------------------------------------");
			return 1;
		}
	}

	public static class ClearInv extends CommandExecute {

		@Override
		public int execute(MapleClient c, String[] splitted) {
			Map<Pair<Short, Short>, MapleInventoryType> eqs = new ArrayMap<Pair<Short, Short>, MapleInventoryType>();
			if (splitted[1].equals("全部")) {
                for (MapleInventoryType type : MapleInventoryType.values()) {
                    for (IItem item : c.getPlayer().getInventory(type)) {
                        eqs.put(new Pair<Short, Short>(item.getPosition(), item.getQuantity()), type);
                    }
                }
            } else if (splitted[1].equals("已裝備道具")) {
                for (IItem item : c.getPlayer().getInventory(MapleInventoryType.EQUIPPED)) {
                    eqs.put(new Pair<Short, Short>(item.getPosition(), item.getQuantity()), MapleInventoryType.EQUIPPED);
                }
            } else if (splitted[1].equals("武器")) {
                for (IItem item : c.getPlayer().getInventory(MapleInventoryType.EQUIP)) {
                    eqs.put(new Pair<Short, Short>(item.getPosition(), item.getQuantity()), MapleInventoryType.EQUIP);
                }
            } else if (splitted[1].equals("消耗")) {
                for (IItem item : c.getPlayer().getInventory(MapleInventoryType.USE)) {
                    eqs.put(new Pair<Short, Short>(item.getPosition(), item.getQuantity()), MapleInventoryType.USE);
                }
            } else if (splitted[1].equals("裝飾")) {
                for (IItem item : c.getPlayer().getInventory(MapleInventoryType.SETUP)) {
                    eqs.put(new Pair<Short, Short>(item.getPosition(), item.getQuantity()), MapleInventoryType.SETUP);
                }
            } else if (splitted[1].equals("其他")) {
                for (IItem item : c.getPlayer().getInventory(MapleInventoryType.ETC)) {
                    eqs.put(new Pair<Short, Short>(item.getPosition(), item.getQuantity()), MapleInventoryType.ETC);
                }
            } else if (splitted[1].equals("特殊")) {
                for (IItem item : c.getPlayer().getInventory(MapleInventoryType.CASH)) {
                    eqs.put(new Pair<Short, Short>(item.getPosition(), item.getQuantity()), MapleInventoryType.CASH);
                }
            } else {
                c.getPlayer().dropMessage(6, "[全部/已裝備道具/武器/消耗/裝飾/其他/特殊]");
            }
            for (Entry<Pair<Short, Short>, MapleInventoryType> eq : eqs.entrySet()) {
                MapleInventoryManipulator.removeFromSlot(c, eq.getValue(), eq.getKey().left, eq.getKey().right, false, false);
            }
            return 1;
		}
	}
	
	// gainExpMap 给与当前地图玩家经验值
	public static class gainExpMap extends CommandExecute {

        @Override
        public int execute(MapleClient c, String[] splitted) {
        	if (splitted.length < 2) {
        		c.getPlayer().dropMessage(6, "给与当前地图所有玩家经验用法: !gainexpmap [数量]");
        		return 0;
        	}
            int quantity = Integer.parseInt(splitted[1]);
            for (ChannelServer cserv : ChannelServer.getAllInstances()) {
                for (MapleCharacter mch : cserv.getPlayerStorage().getAllCharacters()) {
                    if (c.getPlayer().getMapId() == mch.getMapId()) {
                        mch.gainExp(quantity, true, true, true);
                    }
                }
            }
            
            for (ChannelServer cserv1 : ChannelServer.getAllInstances()) {
                for (MapleCharacter mch : cserv1.getPlayerStorage().getAllCharacters()) {
                    if (c.getPlayer().getMapId() == mch.getMapId()) {
                        mch.startMapEffect("管理员发放 " + quantity + " 经验给当前地图在线的所以玩家！快感谢管理员吧！", 5121020);
                    }
                }
            }
            return 1;
        }
    }
	
	// gainMesoMap 给与当前地图玩家冒险币
    public static class gainMesoMap extends CommandExecute {

        @Override
        public int execute(MapleClient c, String[] splitted) {
        	if (splitted.length < 2) {
        		c.getPlayer().dropMessage(6, "给与当前地图所有玩家冒险币用法: !gainmesomap [数量]");
        		return 0;
        	}
            int quantity = Integer.parseInt(splitted[1]);
            
            if (quantity > 100000000) {
            	c.getPlayer().dropMessage(6, "地主家也没有余粮啊!!!");
            	return 0;
            }
            
            for (ChannelServer cserv : ChannelServer.getAllInstances()) {
                for (MapleCharacter mch : cserv.getPlayerStorage().getAllCharacters()) {
                    if (c.getPlayer().getMapId() == mch.getMapId()) {
                        mch.gainMeso(quantity, true);
                    }
                }
            }
            for (ChannelServer cserv1 : ChannelServer.getAllInstances()) {
                for (MapleCharacter mch : cserv1.getPlayerStorage().getAllCharacters()) {
                    if (c.getPlayer().getMapId() == mch.getMapId()) {
                        mch.startMapEffect("管理员发放 " + quantity + " 冒险币给当前地图在线的所有玩家！快感谢管理员吧！", 5121020);
                    }

                }
            }
            return 1;
        }
    }
    
    // gainItemMap 给与当前地图玩家道具
    public static class gainItemMap extends CommandExecute {

        @Override
        public int execute(MapleClient c, String[] splitted) {
            if (!c.getPlayer().isAdmin()) {
                return 0;
            }
            if (splitted.length < 3) {
                c.getPlayer().dropMessage(6, "给与当前地图所有玩家道具用法: !gainitemmap [物品ID] [数量]");
                return 0;
            }
            
            MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
            int item = Integer.parseInt(splitted[1]); // 道具id
            int quantity = Integer.parseInt(splitted[2]);
            String mz = ii.getName(item);
            for (ChannelServer cserv : ChannelServer.getAllInstances()) {
                for (MapleCharacter mch : cserv.getPlayerStorage().getAllCharacters()) {
                    if (c.getPlayer().getMapId() == mch.getMapId()) {
                        MapleInventoryManipulator.addById(mch.getClient(), item, (short) quantity, (byte) 0);
                    }
                }
            }
            for (ChannelServer cserv1 : ChannelServer.getAllInstances()) {
                for (MapleCharacter mch : cserv1.getPlayerStorage().getAllCharacters()) {
                    if (quantity <= 1) {
                        if (c.getPlayer().getMapId() == mch.getMapId()) {
                            mch.startMapEffect("管理员发放 【" + mz + "】 物品给当前地图在线的所有玩家！快感谢管理员吧！", 5120000);
                        }

                    } else {
                        if (c.getPlayer().getMapId() == mch.getMapId()) {
                            mch.startMapEffect("管理员发放 【" + mz + "】 物品 【" + quantity + "】 个给当前地图在线的所以玩家！快感谢管理员吧！", 5120000);
                        }

                    }
                }
            }
            return 1;
        }
    }
    
    // giveItem 给与玩家道具
    public static class giveItem extends CommandExecute {

        @Override
        public int execute(MapleClient c, String[] splitted) {
            if (splitted.length < 4) {
                c.getPlayer().dropMessage(6, "给与指定玩家道具用法: !giveitem [角色名字]  [物品ID] [数量]");
                return 0;
            }
            
            String name = splitted[1]; // 玩家名称
            int item = Integer.parseInt(splitted[2]); // 道具id
            int quantity = Integer.parseInt(splitted[3]); // 道具数量
            for (ChannelServer cserv : ChannelServer.getAllInstances()) {
                for (MapleCharacter mch : cserv.getPlayerStorage().getAllCharacters()) {
                    if (mch.getName().equals(name)) {
                        MapleInventoryManipulator.addById(mch.getClient(), item, (short) quantity, (byte) 0);
                        c.getPlayer().dropMessage(6, "给予成功！");
                    }
                }
            }
            return 1;
        }
    }
    
    // mesoEverybody 全区发钱
	public static class mesoEverybody extends CommandExecute {
		public int execute(MapleClient c, String[] splitted) {
			if (c.getPlayer().getGMLevel() != 3) {
				c.getPlayer().dropMessage("无权限使用!");
				return 0;
			}
			if (splitted.length < 2) {
				c.getPlayer().dropMessage(splitted[0] + " <金币量>");
				return 0;
			}
			
			int ret = 0;
			int gain = Integer.parseInt(splitted[1]);
			
            if (gain > 20000000) {
            	c.getPlayer().dropMessage(6, "地主家也没有余粮啊!!!");
            	return 0;
            }
			
			for (MapleCharacter mch : c.getChannelServer().getPlayerStorage().getAllCharactersThreadSafe()) {
				mch.gainMeso(gain, true);
				ret++;
			}
			for (ChannelServer cserv1 : ChannelServer.getAllInstances()) {
				for (MapleCharacter mch : cserv1.getPlayerStorage().getAllCharacters()) {
					mch.startMapEffect("管理员发放" + gain + "冒险币给在线的所有玩家！祝您玩的开心玩的快乐", 5121009);
				}
			}
			c.getPlayer().dropMessage(6, "命令使用成功，当前共有: " + ret + " 个玩家获得: " + gain + " 冒险币 " + " 总计: " + ret * gain);

			return 1;
		}
	}
}
